package com.ictech.print.protocal;

import android.text.TextUtils;
import android.util.Log;

import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.WriterException;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.QRCodeWriter;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import com.ictech.print.utils.JsonUtil;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

/**
 * 项目名称：print
 * 创建人：bear
 * 创建时间：2018/12/24
 */

public class ProtocolPrinter {

    private final String TAG = "ProtocolPrinter";

    /*可打印区域约为45mm，默认横向移动单位为1/8mm，默认纵向移动单位为1/7mm*/
    //private final int PaperSize = 45;
    /*80mm系列打印机，可打印区域约为80mm，默认横向移动单位为1/8mm，默认纵向移动单位为1/7mm*/
    private final int PaperSize = 80;
    /*80mm系列打印机，一行大约可打1*1规格的字符48个,最后一列的“单位”占了4个位置，所以计算空格时需要减去*/
    private final int charNums = 48 - 4;
    private final byte[] Init = {0x1B,0x40};             //初始化打印机
    private final byte[] LeftMargin = {0x1D,0x4c};      //左边距
    private final byte[] AbsLocation = {0x1B,0x24};     //绝对打印位置
    private final byte[] PrintWidth = {0x1D,0x57};      //打印区域宽度（宽度为｛（nL+nH*256）*横向移动单位｝英寸，若超出范围，则打印宽度为：可打印区域-左边距）
    private final byte[] PrintMM = {0x1B,0x4A};         //打印并走纸n英寸（（n*纵向或横向移动单位）英寸，最大走纸距离956mm）
    private final byte[] PrintLine = {0x0A};             //打印并换行
    private final byte[] PrintLines = {0x1B,0x64};      //打印并走纸n行
    private final byte[] TextSize = {0x1D,0x21};        //字符大小
    private final byte[] TextMode = {0x1B,0x4D};        //选择字体
    private final byte[] HirLocation = {0x1D,0x48};     //选择hir的打印位置（hir为对条形码内容的注释字符）
    private final byte[] AlignMode = {0x1B,0x61};       //选择对齐方式
    private final byte[] setMoveUnit = {0x1D, 0x50};    //设置横向和纵向移动单位

    public ProtocolPrinter(int[] data){
        super();
    }

    public void ReadData(int[] data) {

    }

    /**
     * 打印二维码
     * @param size          二维码大小（水平方向位图字节数，每个字节可以代表8个像素点，如20，则二维码大小为160dip*160dip）
     * @param content       二维码内容
     * @param align         二维码对齐方式，0：左对齐，1：居中，2：右对齐
     * @return              打印二维码字节数组
     */
    public byte[]  printMyQRCode(int size, String content, int align){
        ArrayList<byte[]> mList = new ArrayList<byte[]>();
        mList.add(Init);
        mList.add(setAlignMode(align));
        mList.add(printQRCode(size,content));
//        mList.add(PrintLine);
        int mListLen = 0;
        for (byte[] a: mList){
            mListLen = mListLen + a.length;
        }
        byte[] AddList = new byte[mListLen];
        mListLen = 0;
        for (byte[] a: mList){
            System.arraycopy(a,0,AddList,0+mListLen,a.length);
            mListLen = mListLen + a.length;
        }
        return AddList;
    }

    /**
     * 打印条形码
     * @param content       条形码内容
     * @param widthByte     条形码宽度字节数
     * @param heightByte    条形码高度字节数
     * @param align         条形码对齐方式
     * @param hir           是否打印条形码内容
     * @return              条形码字节数组
     */
    public byte[] printMyBarCode(String content, int widthByte, int heightByte, int align, boolean hir){
        ArrayList<byte[]> mList = new ArrayList<byte[]>();
        mList.add(Init);
        mList.add(setAlignMode(align));
        mList.add(printBarCode(content,widthByte,heightByte));
        if (hir){
            mList.add(printStr(1, 1, content));
//            mList.add(PrintLine);
        }
//        mList.add(PrintLine);

        int mListLen = 0;
        for (byte[] a: mList){
            mListLen = mListLen + a.length;
        }
        byte[] AddList = new byte[mListLen];
        mListLen = 0;
        for (byte[] a: mList){
            System.arraycopy(a,0,AddList,0+mListLen,a.length);
            mListLen = mListLen + a.length;
        }
        return AddList;
    }

    /**
     * 使用打印机自带的条码打印命令打印条码
     * （58系列打印机极限可以打印14个字符，80系列打印机极限可以打印23个字符）
     * @param content       条码内容
     * @param align         条码对齐方式 （0：右对齐， 1：居中， 2右对齐）
     * @return              条形码字节数组
     */
    public byte[] printMyCode128(String content, int align) {
        ArrayList<byte[]> mList = new ArrayList<byte[]>();
        mList.add(Init);
        mList.add(setAlignMode(align));
        mList.add(setHirLocation(2));
        mList.add(printCode128(70, 2, content));
//        mList.add(printMM(5));
//        mList.add(PrintLine);

        int mListLen = 0;
        for (byte[] a: mList){
            mListLen = mListLen + a.length;
        }
        byte[] AddList = new byte[mListLen];
        mListLen = 0;
        for (byte[] a: mList){
            System.arraycopy(a,0,AddList,0+mListLen,a.length);
            mListLen = mListLen + a.length;
        }
        return AddList;
    }


    /**
     * 打印消费凭证
     * @param content   文本内容
     * @return  文本数组
     */
    public byte[] printBill(String content){
        try {
            ArrayList<byte[]> mList = new ArrayList<byte[]>();
            JSONArray orders = new JSONArray(content);
            for (int i = 0; i < orders.length(); i = i + 1) {
                JSONObject order = orders.getJSONObject(i);
                String orderId = order.getString("orderId");
                String time = order.getString("time");
                mList.add(Init);
                mList.add(setAlignMode(1));         //居中
                mList.add(printStr(2, 2, "交易信息"));
                mList.add(PrintLine);

                mList.add(Init);
                mList.add(setLeftMargin(0f));
                mList.add(printMM(3));
                mList.add(PrintLine);

                mList.add(Init);
                mList.add(setLeftMargin(0f));
                mList.add(printStr(1, 1, ("订单号码：" + orderId)));
                mList.add(PrintLine);

                mList.add(Init);
                mList.add(setLeftMargin(0f));
                mList.add(printStr(1, 1, ("交易时间：" + time)));
                mList.add(PrintLine);

                mList.add(Init);
                mList.add(setAlignMode(1));         //居中
                mList.add(printStr(1, 1, "------------------------------------------------"));
                mList.add(PrintLine);

                mList.add(Init);
                mList.add(setLeftMargin(0f));
                mList.add(printStr(1, 1, "商品"));
                mList.add(printStr(1, 1, "          "));
                mList.add(printStr(1, 1, "重量"));
                mList.add(printStr(1, 1, "          "));
                mList.add(printStr(1, 1, "单价"));
                mList.add(printStr(1, 1, "          "));
                mList.add(printStr(1, 1, "单位"));
                mList.add(PrintLine);

                JSONArray detail = order.getJSONArray("detail");
                for (int j = 0; j < detail.length(); j++) {
                    JSONObject commodity = (JSONObject) detail.get(j);
                    String name = commodity.getString("name");
                    String weight = commodity.getString("weight");
                    String price = commodity.getString("price");
                    String weight_unit = commodity.getString("weight_unit");

                    /*商品名称--与其余参数同行*/
                    int nameLen = name.length();
                    if (nameLen <= 6) {                          //少于6个字符可在一行进行打印
                        mList.add(setLeftMargin(0.0f));
                        mList.add(printStr(1, 1, name));
                        /*计算需要补全的空格，一个汉字占2个空格*/
                        String blank = "  ";
                        int blankNums = 6 - nameLen;
                        while (blankNums-- > 0) {
                            blank = blank + "  ";
                        }
                        mList.add(printStr(1, 1, blank));
                    }else {                                     //多余6个字符需多行打印
                        int lines = nameLen / 6;        //行数
                        int remain = nameLen % 6;       //剩余字符
                        if (remain != 0) {
                            lines = lines + 1;
                        }
                        for (int line = 0; line < lines; line++) {
                            if (((line * 6) + 6) < nameLen) {
                                mList.add(setLeftMargin(0.0f));
                                mList.add(printStr(1, 1, name.substring(line * 6, (line * 6) + 6)));
                                mList.add(PrintLine);
                            } else {
                                mList.add(setLeftMargin(0.0f));
                                mList.add(printStr(1, 1, name.substring(line * 6)));
                                /*计算需要补全的空格，一个汉字占2个空格*/
                                String blank = "  ";
                                int blankNums = ((line * 6) + 6) - nameLen;
                                while (blankNums-- > 0) {
                                    blank = blank + "  ";
                                }
                                mList.add(printStr(1, 1, blank));
                            }
                        }
                    }

                     /*根据单位调整重量*/
                    int blankSize = 0;
                    float weight_float = 0;
                    if (weight_unit.equals("0")) {
                        weight_unit = "公斤";
                        weight_float = Float.parseFloat(weight)/1000;
                    }else {
                        weight_unit = "市斤";
                        weight_float = Float.parseFloat(weight)/500;
                    }

                    /*重量*/
                    mList.add(printStr(1, 1, String.valueOf(weight_float)));
                    blankSize = (int) (charNums/3.0f) - weight.length();    //因为有重量、单价、单位，所以除以3
                    if (blankSize > 0) {
                        String blank = "";
                        while (blankSize-- > 0) {
                            blank = blank + " ";
                        }
                        mList.add(printStr(1, 1, blank));
                    }
                    /*单价*/
                    mList.add(printStr(1, 1, price));
                    blankSize = (int) (charNums/3.0f) - price.length();
                    if (blankSize > 0) {
                        String blank = "";
                        while (blankSize-- > 0) {
                            blank = blank + " ";
                        }
                        mList.add(printStr(1, 1, blank));
                    }
                    /*单位*/
                    mList.add(printStr(1, 1, weight_unit));
                    mList.add(PrintLine);
                }

                String totalPrice = order.getString("totalPrice");
                mList.add(Init);
                mList.add(setAlignMode(1));         //居中
                mList.add(printStr(1, 1, "------------------------------------------------"));
                mList.add(PrintLine);

                mList.add(Init);
                mList.add(setLeftMargin(0f));
                mList.add(printStr(1, 1, ("应收金额：" + totalPrice)));
                mList.add(PrintLine);
                mList.add(Init);
                mList.add(setLeftMargin(0f));
                mList.add(printStr(1, 1, ("实收金额：" + totalPrice)));
                mList.add(PrintLine);
                mList.add(Init);
                mList.add(setLeftMargin(0f));
                mList.add(printStr(1, 1, ("找回金额：" + "0")));
                mList.add(PrintLine);

                mList.add(Init);
                mList.add(setAlignMode(1));         //居中
                mList.add(printStr(1, 1, "------------------------------------------------"));
                mList.add(PrintLine);

                /*打印溯源二维码*/
                String trace_url = order.getString("trace_url");
                mList.add(printMyQRCode(30, trace_url, 1));

                /*打印溯源号码*/
                mList.add(Init);
                mList.add(setAlignMode(1));         //居中
                mList.add(printStr(1, 1, "溯源编号：" + trace_url.substring(trace_url.length() - 20, trace_url.length())));
                mList.add(PrintLine);

                mList.add(cutPaper(2, 0));         //切纸
            }
            int mListLen = 0;
            for (byte[] a : mList) {
                mListLen = mListLen + a.length;
            }
            byte[] AddList = new byte[mListLen];
            mListLen = 0;
            for (byte[] a : mList) {
                System.arraycopy(a, 0, AddList, 0 + mListLen, a.length);
                mListLen = mListLen + a.length;
            }
            return AddList;
        } catch (JSONException e) {
            e.printStackTrace();
            Log.i(TAG, e.toString());
            return null;
        }
    }

    /**
     * 设置切纸方式(切纸命令需要在行首所以加上0x0A指令)
     * @param mode 切纸方式：0：全切 1：半切 2：进纸后半切
     * @param len   进纸距离n（公式为：打印位置到切刀距离 + n * 纵向移动单位，n>=0 && n<=255）
     * @return      切纸模式字符数组
     */
    private byte[] cutPaper(int mode, int len){
        switch (mode){
            case 0: {           //貌似不行
                byte[] mMode = new byte[4];
                mMode[0] = 0x0A;
                mMode[1] = 0x1D;
                mMode[2] = 0x56;
                mMode[3] = 0x48;
                return mMode;
            }
            case 1: {           //貌似不行
                byte[] mMode = new byte[4];
                mMode[0] = 0x0A;
                mMode[1] = 0x1D;
                mMode[2] = 0x56;
                mMode[3] = 0x49;
                return mMode;
            }
            case 2: {           //这个可以，但和文档有差异（文档是0x66而不是0x42）
                byte[] mMode = new byte[5];
                mMode[0] = 0x0A;
                mMode[1] = 0x1D;
                mMode[2] = 0x56;
                mMode[3] = 0x42;
                if (len > 0 && len <256){
                    mMode[4] = (byte)len;
                }else {
                    mMode[4] = (byte)0x00;
                }
                return mMode;
            }
            default:return new byte[]{};
        }
    }
    /**
     * 设置字符模式
     * @param mode  字符模式：1：普通模式，2：压缩模式，其他值：默认
     * @return      字符模式设置字节数组
     */
    private byte[] setTextMode(int mode){
        byte[] mMode = new byte[3];
        switch (mode){
            case 1: mMode[2] = 0x48;        //普通模式(12*24)
            break;
            case 2: mMode[2] = 0x49;        //压缩模式(9*27)
            break;
            default:return null;
        }
        mMode[0] = TextMode[0];
        mMode[1] = TextMode[1];
        return mMode;
    }

    /**
     * 设置对齐方式
     * @param mode  0：左对齐，1：居中，2：右对齐，其他值：左对齐
     * @return      对齐方式字节数组
     */
    private byte[] setAlignMode(int mode){
        byte[] mAlign = new byte[3];
        mAlign[0] = AlignMode[0];
        mAlign[1] = AlignMode[1];
        if (mode >= 0 && mode <=2 ){
            mAlign[2] = (byte)mode;
        }else {
            mAlign[2] = (byte)0x00;
        }
        return mAlign;
    }

    /**
     * (貌似一行只能设置一次)
     * 设置左边距，公式为：(nL + nH * 256) * 横向移动单位
     * 可打印长度默认为45mm左右，横向移动单位默认为1/8mm左右。
     * @param margin     所设置的边距与可打印长度的百分比
     * @return           设置左边距字节数组
     */
    private byte[] setLeftMargin(float margin){
        if (margin>1 || margin<0){
            margin = 1;
        }else if(margin == 0){
            return new byte[]{LeftMargin[0],LeftMargin[1],0,0};
        }
        byte[] mMargin = new byte[4];
        mMargin[0] = LeftMargin[0];
        mMargin[1] = LeftMargin[1];
        int nL = 0;
        if (PaperSize*margin > 32){                           //nH=0时,nL能表示的最大距离大约是32mm（256*横向移动单位）
            int nH = (int) ((PaperSize*margin)/32);
            mMargin[3] = (byte)nH;                           //nH=1时，至少有32mm
            nL = (int) ((PaperSize * margin - 32 * nH) * 8);
//            Log.i(TAG,"nH:" + String.valueOf(nH));
//            Log.i(TAG,"nL:" + String.valueOf(nL));
        }else {
            mMargin[3] = (byte)0x00;
            nL = (int)(PaperSize*margin*8);
        }
        mMargin[2] = (byte)nL;
        return mMargin;
    }

    /**
     * (貌似一行只能设置一次)
     * 设置绝对打印位置，公式为：(nL + nH * 256) * 横向移动单位
     * @param location  所设置的位置与可打印长度的百分比
     * @return           设置绝对打印位置字节数组
     */
    private byte[] setAbsLocation(float location){
        if (location>1 || location<0){
            location = 1;
        }else{
//            Log.i(TAG,"nL:" + "0");
            return new byte[]{AbsLocation[0],AbsLocation[1],0,0};
        }
        byte[] mLocation = new byte[4];
        mLocation[0] = AbsLocation[0];
        mLocation[1] = AbsLocation[1];
        int nL = 0;
        if (PaperSize*location > 32){                           //nH=0时,nL能表示的最大距离大约是32mm（256*横向移动单位）
            int nH = (int) ((PaperSize*location)/32);
            mLocation[3] = (byte)nH;                           //nH=1时，至少有32mm
            nL = (int) ((PaperSize * location - 32 * nH) * 8);
//            Log.i(TAG,"nH:" + String.valueOf(nL));
//            Log.i(TAG,"nL:" + String.valueOf(nL));
        }else {
            mLocation[3] = (byte)0x00;
            nL = (int)(PaperSize*location*8);
//            Log.i(TAG,"nL:" + String.valueOf(nL));
        }
        mLocation[2] = (byte)nL;
        return mLocation;
    }

    /**
     * 设置HIR的打印位置
     * @param location      0：不打印，1：在上方打印，2：在下方打印，3：上下方均打印
     * @return               HIR打印位置字节数组
     */
    private byte[] setHirLocation(int location){
        byte[] mHir = new byte[3];
        mHir[0] = HirLocation[0];
        mHir[1] = HirLocation[1];
        if (location>=0 && location <= 3){
            mHir[2] = (byte)location;
        }else {
            mHir[2] = (byte)0x00;
        }
        return mHir;
    }

    /**
     * 走纸mm毫米，公式为mm * 横向移动单位
     * 默认情况下最大走纸距离约为32mm（255/8）
     * @param mm        打印的距离，单位为毫米
     * @return          走纸mm毫米字节数组
     */
    private byte[] printMM(int mm){
        if (mm < 0){
            mm = 0;
        }else if (mm > 32){
            return new byte[]{PrintMM[0], PrintMM[1],(byte) 255};
        }
        byte[] MM = new byte[3];
        MM[0] = PrintMM[0];
        MM[1] = PrintMM[1];
        MM[2] = (byte)(mm*8);
        return MM;
    }

    /**
     * 打印并走纸n行
     * @param n     走纸的行数
     * @return      打印并走纸n行字节数组
     */
    private byte[] printLines(int n){
        byte[] mLines = new byte[3];
        mLines[0] = PrintLines[0];
        mLines[1] = PrintLines[1];
        if (n > 0 && n < 256){
            mLines[2] = (byte) n;
        }else {
            mLines[2] = (byte)0x00;
        }
        return mLines;
    }

    /**
     * 打印字符串
     * @param height     字符的高度（几倍的字符模式）
     * @param width     字符的宽度（几倍的字符模式）
     * @param text      需要打印的字符
     * @return          打印字符串的字节数组
     */
    private byte[] printStr(int height, int width, String text){
        byte size = 0x00;
        switch (height){
            case 1: size = (byte) (size | 0x00);
                break;
            case 2: size = (byte) (size | 0x01);
                break;
            case 3: size = (byte) (size | 0x02);
                break;
            case 4: size = (byte) (size | 0x03);
                break;
            case 5: size = (byte) (size | 0x04);
                break;
            case 6: size = (byte) (size | 0x05);
                break;
            case 7: size = (byte) (size | 0x06);
                break;
            case 8: size = (byte) (size | 0x07);
                break;
            default:break;
        }
        switch (width){
            case 1: size = (byte) (size | 0x00);
                break;
            case 2: size = (byte) (size | 0x10);
                break;
            case 3: size = (byte) (size | 0x20);
                break;
            case 4: size = (byte) (size | 0x30);
                break;
            case 5: size = (byte) (size | 0x40);
                break;
            case 6: size = (byte) (size | 0x50);
                break;
            case 7: size = (byte) (size | 0x60);
                break;
            case 8: size = (byte) (size | 0x70);
                break;
            default:break;
        }
        try {
            byte [] textByte = text.getBytes("gbk");
            byte[] mTextSize = new byte[textByte.length + 3];
            mTextSize[0] = TextSize[0];
            mTextSize[1] = TextSize[1];
            mTextSize[2] = size;
            System.arraycopy(textByte,0,mTextSize,3,textByte.length);
            return  mTextSize;
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 打印code128条形码
     * @param height     条形码高度：1~255（默认值162）
     * @param width     条形码宽度：2~6 （默认值3）
     * @param code128   需要转换为code128条形码的字符串
     * @return          code128条形码字节数组
     */
    private byte[] printCode128(int height, int width, String code128){
        int len = code128.length();
        byte[] mCode128 = new byte[3+3+6+len];
        //设置条形码高度
        mCode128[0] = 0x1D;                     //byte0~1为命令
        mCode128[1] = 0x68;
        if (height>=1 && height<=255){
            mCode128[2] = (byte)height;          //自定义值
        }else {
            mCode128[2] = (byte)162;
        }
        //设置条形码宽度
        mCode128[3] = 0x1D;                     //byte3~4为命令
        mCode128[4] = 0x77;
        if (width>=2 && width<=6){
            mCode128[5] = (byte)width;          //自定义值
        }else {
            mCode128[5] = (byte)3;
        }
        //设置code128
        mCode128[6] = 0x1D;                     //byte6~7为命令
        mCode128[7] = 0x6B;
        mCode128[8] = 0x49;                     //条码类型为code128
        mCode128[9] = (byte)(len + 2);          //需要打印的字符长度+字符集选择命令长度
        mCode128[10] = 0x7B;                    //用字符集B（与ASCⅡ对应）
        mCode128[11] = 0x42;

        try {
            System.arraycopy(code128.getBytes("gbk"),0,mCode128,12,len);
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return mCode128;
    }


    /**
     * 打印二维码
     * @param size          二维码大小（水平方向位图字节数，每个字节可以代表8个像素点，如20，则二维码大小为160dip*160dip）
     * @param content       二维码内容
     * @return              二维码字节数组
     */
    private byte[] printQRCode(int size, String content){
        int width = size * 8;
        int height = size * 8;
        if(content.equals("") || content == null){
            return null;
        }
        byte[] mQRcode = new byte[3+1+2+2+ (size * height)];
        mQRcode[0] = 0x1D;      //打印光栅位图命令
        mQRcode[1] = 0x76;
        mQRcode[2] = 0x30;
        mQRcode[3] = 0x30;      //正常位图模式
        //设置水平方向位图字节数
        if (size > 255){
            mQRcode[4] = (byte) (size % 256);
            mQRcode[5] = (byte) (size / 256);
        }else {
            mQRcode[4] = (byte) size;
            mQRcode[5] = (byte) 0x00;
        }
        //设置水平方向位图像素点数
        if (height > 255){
            mQRcode[6] = (byte) (height % 256);
            mQRcode[7] = (byte) (height / 256);
        }else {
            mQRcode[6] = (byte) height;
            mQRcode[7] = (byte) 0x00;
        }
        /*图片编码设置*/
        Map<EncodeHintType, Object> hints = new HashMap<EncodeHintType, Object>();
        hints.put(EncodeHintType.CHARACTER_SET, "utf-8");                        //字符类型
        hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);     //容错级别
        hints.put(EncodeHintType.MARGIN, 1);                                        //设置空白边距的宽度
        try {
            /*生成二维码矩阵*/
            QRCodeWriter mQRCodeWriter = new QRCodeWriter();
            BitMatrix bitMatrix = mQRCodeWriter.encode(content, BarcodeFormat.QR_CODE, width, height, hints);   //将文本内容转换为二维码
            byte mByte = (byte) 0xFF;
            for (int y=0; y<height; y++){
                for (int x=0, b=0; x<width; x++){
                    if (bitMatrix.get(x,y)){
                        mByte = (byte) (mByte | (byte) (0x80/ Math.pow(2,b)));
                    }else {
                        mByte = (byte) (mByte & ~((byte)(0x80/ Math.pow(2,b))));
                    }
                    b++;
                    if (b>7){
                        mQRcode[8 + y*size + x/8] = mByte;
                        b=0;
                    }
                }
            }

        } catch (WriterException e) {
            Log.i(TAG,"生成二维码错误");
            e.printStackTrace();
            return null;
        }
        return mQRcode;
    }

    /**
     * 打印条形码
     * @param content      条形码内容
     * @param widthByte    条形码宽度（水平方向位图字节数，每个字节可以代表8个像素点，如20，则条形码宽度为160dip，
     *                       在正常位图模式下，打印机分辨率为200dpi)
     *                       对于58系列打印机：打印机最大打印长度约为1.8inch，则可以打印长度为360dip的图片，即45个字节宽度
     *                       对于80系列打印机：打印机最大打印长度约为3.2inch，则可以打印长度为640dip的图片，即80个字节宽度
     * @param heightByte   条形码高度 （垂直方向位图字节数）
     * @return              条形码字节数组
     */
    private byte[] printBarCode(String content, int widthByte, int heightByte){
        if (TextUtils.isEmpty(content)){
            return null;
        }
        int width = widthByte * 8;
        int height = heightByte * 8;
        byte[] mBarCode = new byte[3+1+2+2+ (widthByte * height)];
        mBarCode[0] = 0x1D;      //打印光栅位图命令
        mBarCode[1] = 0x76;
        mBarCode[2] = 0x30;
        mBarCode[3] = 0x30;      //正常位图模式（200dip/inch）
        //设置水平方向位图字节数
        if (widthByte > 255){
            mBarCode[4] = (byte) (widthByte % 256);
            mBarCode[5] = (byte) (widthByte / 256);
        }else {
            mBarCode[4] = (byte) widthByte;
            mBarCode[5] = (byte) 0x00;
        }
        //设置垂直方向位图像素点数
        if (height > 255){
            mBarCode[6] = (byte) (height % 256);
            mBarCode[7] = (byte) (height / 256);
        }else {
            mBarCode[6] = (byte) height;
            mBarCode[7] = (byte) 0x00;
        }
        /*图片编码设置*/
        Map<EncodeHintType, Object> hints = new HashMap<EncodeHintType, Object>();
        hints.put(EncodeHintType.CHARACTER_SET, "utf-8");                        //字符类型
        hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);     //容错级别
//        hints.put(EncodeHintType.MARGIN, 1);                                        //设置空白边距的宽度
        try {
            /*生成二维码矩阵*/
            MultiFormatWriter mBarCodeWriter = new MultiFormatWriter();
            BitMatrix bitMatrix = mBarCodeWriter.encode(content, BarcodeFormat.CODE_128, width, height, hints);   //将文本内容转换为条形码
            byte mByte = (byte) 0xFF;
            /*将点阵转换为热敏打印机数据*/
            for (int y=0; y<height; y++){
                for (int x=0, b=0; x<width; x++){
                    if (bitMatrix.get(x,y)){
                        mByte = (byte) (mByte | (byte) (0x80/ Math.pow(2,b)));
                    }else {
                        mByte = (byte) (mByte & ~((byte)(0x80/ Math.pow(2,b))));
                    }
                    b++;
                    if (b>7){
                        mBarCode[8 + y*widthByte + x/8] = mByte;
                        b=0;
                    }
                }
            }

        } catch (WriterException e) {
            Log.i(TAG,"生成条形码错误");
            e.printStackTrace();
            return null;
        }
        return mBarCode;
    }
}
